package org.emet.service;

import java.io.File;
import java.io.FilenameFilter;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.text.MessageFormat;

import org.emet.dao.ArchiveDao;
import org.emet.jee.BusinessException;
import org.emet.jee.console.dao.sys.DBDao;
import org.emet.jee.console.entity.sys.Archive;
import org.emet.jee.console.entity.sys.DB;
import org.emet.jee.core.dao.Page;
import org.emet.jee.core.dao.arch.CurrentArchHolder;
import org.emet.service.db.BackupRestoreService;
import org.emet.service.dto.ArchiveCriteria;
import org.hibernate.ObjectNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.flex.remoting.RemotingDestination;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
@RemotingDestination
public class ArchiveService {
	@Autowired
	private ArchiveDao archiveDao;
	@Autowired
	private DBDao dbDao;
	private static Logger logger = LoggerFactory.getLogger(ArchiveService.class);

	@Transactional(readOnly = true)
	public String getCurrentName() {
		try {
			Long archId = CurrentArchHolder.get();

			if (archId == null)
				throw new RuntimeException("可能没有登录！或者是bug，当前数据库连接的信息没有放在ThreadLocal中。");

			Archive archive = archiveDao.get(archId);
			if (archive == null)
				return null;
			return archive.getName();
		} catch (ObjectNotFoundException e) {
			logger.error(e.getMessage(), e);
			throw new BusinessException("发生异常!");
		}
	}

	@Transactional(readOnly = true)
	public void backup(Long id) {
		try {
			Archive archive = getArch(id);
			BackupRestoreService backupRestoreService = new BackupRestoreService();
			backupRestoreService.setBakFileName(archive.getName());
			backupRestoreService.setDatabasename(archive.getJdbcSchema());
			backupRestoreService.setPassword(archive.getJdbcPassword());
			backupRestoreService.setUsername(archive.getJdbcUsername());

			DB db = dbDao.get(1L);
			backupRestoreService.setBackUpPath(db.getBackUpPath());
			backupRestoreService.setDBHome(db.getDbHome());
			backupRestoreService.backup();
		} catch (Exception e) {
			throw new BusinessException(e.getMessage());
		}
	}

	@Transactional(readOnly = true)
	public void restore(Long id, String bakFileName) {
		try {
			Archive archive = getArch(id);
			BackupRestoreService backupRestoreService = new BackupRestoreService();
			backupRestoreService.setDatabasename(archive.getJdbcSchema());
			backupRestoreService.setPassword(archive.getJdbcPassword());
			backupRestoreService.setUsername(archive.getJdbcUsername());

			DB db = dbDao.get(1L);
			backupRestoreService.setDBHome(db.getDbHome());
			backupRestoreService.setBakFileName(db.getBackUpPath() + "/" + bakFileName);
			backupRestoreService.restore();
		} catch (Exception e) {
			throw new BusinessException(e.getMessage());
		}
	}

	@Transactional(readOnly = true)
	public String[] listBackupFiles() {
		DB db = dbDao.get(1L);
		String backUpPath = db.getBackUpPath();
		File file = new File(backUpPath);
		return file.list(new FilenameFilter() {

			public boolean accept(File dir, String name) {
				return name.endsWith("sql");
			}
		});
	}

	public void save(Archive entity) {
		try {
			String url = MessageFormat.format("jdbc:mysql://{0}:{1}/{2}", entity.getJdbcServer(), entity.getJdbcPort()
					+ "", entity.getJdbcSchema());
			DriverManager.getConnection(url, entity.getJdbcUsername(), entity.getJdbcPassword());
		} catch (SQLException e1) {
			logger.error(e1.getMessage(), e1);
			throw new BusinessException("数据库连接错误，请检测您输入的数据库连接信息。");
		}
		try {
			archiveDao.save(entity);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new BusinessException("发生异常!");
		}
	}

	@Transactional(readOnly = true)
	public Archive getArch(Long id) {
		try {
			return archiveDao.get(id);
		} catch (ObjectNotFoundException e) {
			logger.error(e.getMessage(), e);
			throw new BusinessException("发生异常!");
		}
	}

	public void del(Long... ids) {
		for (Long id : ids) {
			if (notExist(id)) {
				continue;
			}
			try {
				archiveDao.delete(id);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
				throw new BusinessException("发生异常!");
			}
		}
	}

	private boolean notExist(Long id) {
		return getArch(id) == null;
	}

	@Transactional(readOnly = true)
	public Page<Archive> search(Page<Archive> page, ArchiveCriteria criteria) {
		try {
			return archiveDao.search(page, criteria);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new BusinessException("发生异常!");
		}
	}
}
